local assets = {
	Asset("ANIM", "anim/beefalo_basic.zip"),
	Asset("ANIM", "anim/beefalo_actions.zip"),
	Asset("ANIM", "anim/beefalo_baby_build.zip"),
	Asset("SOUND", "sound/beefalo.fsb"),
	Asset("ANIM", "anim/musha_arom.zip"),
	Asset("ANIM", "anim/musha_arong.zip")
}

local prefabs = {
	"meat",
	"poop",
	"beefalowool",
	"beefalo"
}

local sounds = {
	walk = "dontstarve/creatures/beefalo_baby/walk",
	grunt = "dontstarve/creatures/beefalo_baby/grunt",
	yell = "dontstarve/creatures/beefalo_baby/yell",
	swish = "dontstarve/creatures/beefalo_baby/tail_swish",
	curious = "dontstarve/creatures/beefalo_baby/curious",
	angry = "dontstarve/creatures/beefalo_baby/angry"
}

local LootTable = {
	{"smallmeat", "beefalowool"},
	{"smallmeat", "smallmeat", "beefalowool"},
	{"smallmeat", "smallmeat", "meat", "beefalowool"},
	{"smallmeat", "meat", "meat", "meat", "beefalowool", "beefalowool"},
	{"meat", "meat", "meat", "meat", "beefalowool", "beefalowool"},
	{}
}

local brain = require "brains/musha_babybeefalobrain"

local function order(inst, commander, action)
	if inst.ownerid == commander.userid then
		local dx = inst.Transform:GetWorldPosition().x - commander.Transform:GetWorldPosition().x
		local dy = inst.Transform:GetWorldPosition().y - commander.Transform:GetWorldPosition().y
		local distance = math.sqrt(math.pow(dx, 2) + math.pow(dy, 2))
		if distance > 20 then
			commander.components.talker:Say(STRINGS.MUSHA_TALK_ORDER_ARONG_LOST)
			return
		end
		if action == "stay" then
			inst.components.follower:SetLeader(commander)
			commander.components.talker:Say(STRINGS.MUSHA_TALK_ORDER_ARONG_FOLLOW)
		elseif action == "follow" then
			inst.components.follower:SetLeader(nil)
			inst.components.talker:Say(STRINGS.MUSHA_TALK_ORDER_ARONG_STAY)
		end
	end
end

local function OnAttacked(inst, data)
	if not inst.components.health:IsDead() then
		if inst.components.health:GetPercent() >= .8 then
			SpawnPrefab("green_leaves").Transform:SetPosition(inst:GetPosition():Get())
		elseif inst.components.health:GetPercent() < .8 and inst.components.health:GetPercent() >= .6 then
			SpawnPrefab("yellow_leaves").Transform:SetPosition(inst:GetPosition():Get())
		elseif inst.components.health:GetPercent() < .6 and inst.components.health:GetPercent() >= .4 then
			SpawnPrefab("orange_leaves").Transform:SetPosition(inst:GetPosition():Get())
		elseif inst.components.health:GetPercent() < .4 then
			SpawnPrefab("red_leaves").Transform:SetPosition(inst:GetPosition():Get())
		end
		if data.attacker:HasTag("_musha") and data.attacker == inst.components.follower.leader then
			inst.components.talker.Say("")
		else
			inst.components.combat:SetTarget(data.attacker)
			inst.components.combat:ShareTarget(
				data.attacker,
				30,
				function(dude)
					return dude:HasTag("beefalo") and not dude:HasTag("player") and not dude.components.health:IsDead()
				end,
				5
			)
		end
	end
end

local function OnEat(inst, food)
	--inst.sg:GoToState("eat")
	inst.sg:GoToState("graze")
	inst.components.hunger:DoDelta(5)
	inst.SoundEmitter:PlaySound("dontstarve/beefalo/chew")
	local food_value =
		food.components.edible and
		0.3 * food.components.edible.hungervalue + 0.2 * food.components.edible.sanityvalue +
			0.5 * food.components.edible.healthvalue or
		5

	inst.components.growable:ExtendGrowTime(-food_value)

	if inst.components.hunger:GetPercent() >= 1 then
		local fx = SpawnPrefab("poopcloud")
		fx.Transform:SetScale(inst.scale, inst.scale, inst.scale)
		fx.Transform:SetPosition(inst:GetPosition():Get())
		local poo = SpawnPrefab("poop")
		poo.Transform:SetScale(inst.scale, inst.scale, inst.scale)
		poo.Transform:SetPosition(inst:GetPosition():Get())
	end

	inst.components.health:DoDelta(inst.components.health.maxhealth * .2, nil, food.prefab)
	inst.components.combat:SetTarget(nil)
end

local function ShouldAcceptItem(inst, item)
	return inst.components.eater:CanEat(item) and not inst.components.combat:HasTarget() and
		inst.components.hunger:GetPercent() < 0.95
end

local function OnGetItemFromPlayer(inst, giver, item)
	if inst.components.eater:CanEat(item) then
		inst.components.eater:Eat(item)
	end
end

local function OnRefuseItem(inst, item)
	inst.sg:GoToState("refuse")
	if inst.components.sleeper:IsAsleep() then
		inst.components.sleeper:WakeUp()
	end
end

local function GetGrowTime()
	return 0.65 * GetRandomWithVariance(TUNING.BABYBEEFALO_GROW_TIME.base, TUNING.BABYBEEFALO_GROW_TIME.random)
end

local function Grown(inst)
	local maxhealth
	if inst.components.growable.stage == 1 then
		inst.scale = 0.25
		maxhealth = 70
	elseif inst.components.growable.stage == 2 then
		inst.scale = 0.4
		maxhealth = 150
	elseif inst.components.growable.stage == 3 then
		inst.scale = 0.6
		maxhealth = 200
	elseif inst.components.growable.stage == 4 then
		if math.random() < 0.5 then
			inst.grown = "arong"
			inst.components.named.possiblenames = STRINGS.ARONG
		else
			inst.grown = "arom"
			inst.components.named.possiblenames = STRINGS.AROM
		end
		inst.components.named:PickNewName()
		inst.scale = 0.75
		maxhealth = 350
		inst.AnimState:SetBuild(inst.grown)
	elseif inst.components.growable.stage == 5 then
		inst.scale = 0.9
		maxhealth = 500
	elseif inst.components.growable.stage == 6 then
		local grown = SpawnPrefab(inst.grown)
		grown.Transform:SetPosition(inst.Transform:GetWorldPosition())
		grown.Transform:SetRotation(inst.Transform:GetRotation())
		grown.components.hunger:SetPercent(inst.components.hunger:GetPercent())
		grown.sg:GoToState("grow_up_pop")
		inst:Remove()
		return
	end
	inst.components.lootdropper:SetLoot(LootTable[inst.components.growable.stage])
	inst.components.sleeper:SetResistance(inst.components.growable.stage)
	inst.Transform:SetScale(inst.scale, inst.scale, inst.scale)
	inst.components.health:SetMaxHealth(maxhealth)
end

local function Grow(inst)
	if inst.components.sleeper:IsAsleep() then
		inst.sg:GoToState("wake")
	end
	inst.sg:GoToState("grow_up")
	Grown(inst)
end

local growth_stages = {
	{name = "Baby", time = GetGrowTime, fn = Grown},
	{name = "LV_1", time = GetGrowTime, fn = Grown, growfn = Grow},
	{name = "LV_2", time = GetGrowTime, fn = Grown, growfn = Grow},
	{name = "LV_3", time = GetGrowTime, fn = Grown, growfn = Grow},
	{name = "LV_4", time = GetGrowTime, fn = Grown, growfn = Grow},
	{name = "GrowUp", time = GetGrowTime, fn = Grown, growfn = Grow}
}

local function fn()
	local inst = CreateEntity()

	inst.entity:AddTransform()
	inst.entity:AddAnimState()
	inst.entity:AddSoundEmitter()
	inst.entity:AddDynamicShadow()
	inst.entity:AddNetwork()

	inst.Transform:SetSixFaced()
	inst.Transform:SetScale(0.25, 0.25, 0.25)

	inst.DynamicShadow:SetSize(2.5, 1.25)

	inst.AnimState:SetBank("beefalo")
	inst.AnimState:SetBuild("beefalo_baby_build")
	inst.AnimState:PlayAnimation("idle_loop", true)

	inst:AddTag("baby")
	inst:AddTag("animal")
	inst:AddTag("companion")
	inst:AddTag("notraptrigger")
	inst:AddTag("musha_beefalo")
	inst:AddTag("musha_babybeefalo")
	inst:AddTag("musha_follower")
	inst:AddTag("herdmember")

	MakeCharacterPhysics(inst, 100, .75)

	inst:AddComponent("talker")
	inst.components.talker.fontsize = 30
	inst.components.talker.colour = Vector3(0.6, 0.9, 0.8, 1)

	inst.entity:SetPristine()

	if not TheWorld.ismastersim then
		return inst
	end

	inst:AddComponent("named")
	inst.components.named.SetName("Musha Beefalo Baby")

	inst.sounds = sounds

	inst:AddComponent("eater")
	inst.components.eater:SetDiet({FOODTYPE.VEGGIE, FOODTYPE.ROUGHAGE}, {FOODTYPE.VEGGIE, FOODTYPE.ROUGHAGE})
	inst.components.eater:SetOnEatFn(OnEat)

	inst:AddComponent("trader")
	inst.components.trader:SetAcceptTest(ShouldAcceptItem)
	inst.components.trader.onaccept = OnGetItemFromPlayer
	inst.components.trader.onrefuse = OnRefuseItem
	inst.components.trader.deleteitemonaccept = false

	inst:AddComponent("combat")
	inst.components.combat.hiteffectsymbol = "beefalo_body"

	inst:AddComponent("health")
	inst.components.health:SetMaxHealth(100)

	inst:AddComponent("hunger")
	inst.components.hunger:SetMax(50)
	inst.components.hunger:SetRate(0)
	inst.components.hunger:SetPercent(0.1)
	-- inst.BreedArong = inst:DoPeriodicTask(0, BreedArong)

	inst:AddComponent("lootdropper")

	inst:AddComponent("inspectable")
	inst:AddComponent("sleeper")

	inst:AddComponent("knownlocations")
	inst:AddComponent("herdmember")
	inst:AddComponent("follower")
	inst.components.follower.canaccepttarget = false

	inst:AddComponent("talker")
	--[[  inst:AddComponent("periodicspawner")
    inst.components.periodicspawner:SetPrefab("poop")
    inst.components.periodicspawner:SetRandomTimes(80, 110)
    inst.components.periodicspawner:SetDensityInRange(20, 2)
    inst.components.periodicspawner:SetMinimumSpacing(8)
    inst.components.periodicspawner:Start()]]
	inst:AddComponent("growable")
	inst.components.growable.stages = growth_stages
	inst.components.growable.springgrowth = false
	inst.components.growable.growonly = true
	inst.components.growable:SetStage(1)
	inst.components.growable:StartGrowing()

	MakeMediumBurnableCharacter(inst, "beefalo_body")

	inst:AddComponent("locomotor") -- locomotor must be constructed before the stategraph
	inst.components.locomotor.walkspeed = 2
	inst.components.locomotor.runspeed = 9
	MakeHauntablePanic(inst)

	inst:SetBrain(brain)

	inst:SetStateGraph("SGBeefalo")

	inst:ListenForEvent("attacked", OnAttacked)

	inst.OnSave = function(inst, data)
		data.grown = inst.grown
		data.ownerid = inst.ownerid
	end

	inst.OnLoad = function(inst, data)
		inst.grown = data.grown
		inst.ownerid = data.ownerid
	end

	inst.order = order

	return inst
end

return Prefab("musha_babybeefalo", fn, assets, prefabs)
